#include "app_buffer.h"
#include "log/log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void app_buffer_swap_buffer(Buffer *buffer){

    pthread_mutex_lock(&buffer->write_lock);
    int temp = -1;
    temp = buffer->read_index;
    buffer->read_index = buffer->write_index;
    buffer->write_index = temp;
    pthread_mutex_unlock(&buffer->write_lock);

}
static SubBuffer *app_buffer_init_subbuffer(int total_size){
    SubBuffer *sub_buffer = (SubBuffer *)malloc(sizeof(SubBuffer));
    if(sub_buffer == NULL){
        return NULL;
    }
    sub_buffer->ptr = (char *)malloc(total_size);
    sub_buffer->total_size = total_size;
    sub_buffer->len = 0;

    return sub_buffer;
}
/**
* @brief 初始化缓冲区
* @param total_size 缓冲区总大小
* @return 返回缓冲区指针
*/
Buffer *app_buffer_init(int total_size){
    Buffer *buffer = (Buffer *)malloc(sizeof(Buffer));
    if(buffer == NULL){
        return NULL;
    }
    buffer->sub_buffers[0] = app_buffer_init_subbuffer(total_size);
    buffer->sub_buffers[1] = app_buffer_init_subbuffer(total_size);
    buffer->read_index = 0;
    buffer->write_index=1; 
    pthread_mutex_init(&buffer->read_lock, NULL);
    pthread_mutex_init(&buffer->write_lock, NULL);
     
    return buffer;
}

/**
* @breif 释放缓冲区
* @param buffer 缓冲区指针
*/
void app_buffer_free(Buffer *buffer){
    free(buffer->sub_buffers[0]->ptr);
    free(buffer->sub_buffers[0]);
    free(buffer->sub_buffers[1]->ptr);
    free(buffer->sub_buffers[1]);

    pthread_mutex_destroy(&buffer->read_lock);
    pthread_mutex_destroy(&buffer->write_lock);
    free(buffer);
}

/**
* @brief 向缓冲区写入数据
* @param buffer 缓冲区指针
* @param data 要写入的数据
* @param data_len 数据长度
* @return 0：成功，-1：失败
*/
int app_buffer_write(Buffer *buffer, char *data, int data_len){
    //
    if(data_len >MAX_MESSAGE_SIZE){
        log_error("data_len is too large");
        return -1;
    }
    pthread_mutex_lock(&buffer->write_lock);
    SubBuffer *write_buffer= buffer->sub_buffers[buffer->write_index];
    
    if((data_len+1)> (write_buffer->total_size - write_buffer->len )){
        log_error("buffer is full");
        pthread_mutex_unlock(&buffer->write_lock);
        return -1;
    }
    write_buffer->ptr[write_buffer->len] = data_len;
    memcpy(write_buffer->ptr+write_buffer->len+1, data, data_len);
    write_buffer->len += data_len+1;
    pthread_mutex_unlock(&buffer->write_lock);
    return 0;
}

/**
* @breif 从缓冲区读取数据
* @param buffer 缓冲区指针
* @param data_buf 存储读取数据的容器
* @param buf_len 容器的大小
* @return 读取的数据长度
*/
int app_buffer_read(Buffer *buffer, char *data_buf, int data_buf_len){
   
   pthread_mutex_lock(&buffer->read_lock);
   SubBuffer *read_buffer=  buffer->sub_buffers[buffer->read_index];
   int read_buffer_len= read_buffer->len;
   if(read_buffer_len <=0){
     app_buffer_swap_buffer(buffer);
     read_buffer=  buffer->sub_buffers[buffer->read_index];
     read_buffer_len= read_buffer->len;
     if(read_buffer_len <=0){
       log_error("buffer is empty");
       pthread_mutex_unlock(&buffer->read_lock);
       return -1;
     }
     
   }
   // 取出第一个字节,表示当前要读取数据的长度
   int data_len = read_buffer->ptr[0];
   if(data_len > data_buf_len){
        log_error("buf_len is too small");
        pthread_mutex_unlock(&buffer->read_lock);
        return -1;
   }
   memcpy(data_buf, read_buffer->ptr+1, data_len);
   int cur_len=read_buffer->len-data_len-1;
   memmove(read_buffer->ptr, read_buffer->ptr+data_len+1, cur_len);
   read_buffer->len = cur_len;
   pthread_mutex_unlock(&buffer->read_lock);
   if(cur_len == 0){ 
    app_buffer_swap_buffer(buffer);
   }
   
   return data_len;
}

